home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / asm4.zip / VTREE.ASM < prev    next >
Assembly Source File  |  1986-02-05  |  9KB  |  294 lines

  1. ;    VTREE -- A Visual Tree-structured subdirectory list
  2. ;    =====
  3. ;
  4. ;        (c) copyright Charles Petzold, 1985
  5. ;
  6. ;        Assembler file:    COM format
  7. ;        Requirements:    DOS 2.0 or higher
  8. ;        Parameters:    Optional Drive Specification
  9.  
  10. CSEG        Segment
  11.         Assume    CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
  12.  
  13.         Org    005Ch
  14. FCB        Label    Byte        ; Will contain drive parameter
  15.  
  16.         Org    0080h
  17. DefaultDTA    Label    Byte        ; Used for look-ahead searches
  18.  
  19.         Org    0100h
  20. Entry:        Jmp    Begin        ; Program entry point
  21.  
  22. ;    Most Data
  23. ;    ---------
  24.  
  25. SearchAsciiz    db    ?,":\*.*",0        ; ? gets drive spec
  26.  
  27.         db    '(C) Copyright Charles Petzold, 1985'
  28.  
  29. DriveError:    db    'Invalid disk drive$'    ; Error message
  30. DosVersError    db    'Requires DOS 2.0 +$'    ; Another error message
  31.  
  32. FirstOrNext    db    0            ; Flag for searches
  33. LevelsIn    dw    0            ; Directory level (0 = root)
  34. SearchString    db    "\*.*",0        ; Asciiz for "all files"
  35. SearchPointer    dw    3 + Offset SearchAsciiz    ; End of SearchAsciiz string
  36. DtaPointer    dw    Offset EndProg        ; Place for current DTA
  37. DashCount    dw    ?            ; For horizontal line count
  38.  
  39. ;    Check drive validity and DOS Version
  40. ;    ------------------------------------
  41.  
  42. Begin:        Cmp    AL,0FFh        ; Check for Valid Drive Specification
  43.         Jnz    DriveSpecOK    ; If OK, proceed
  44.  
  45.         Lea    DX,DriveError    ; Otherwise print an error message!
  46. ErrorExit:    Mov    AH,9        ; Print string 
  47.         Int    21h        ;   by calling DOS
  48.  
  49.         Int    20h        ; And exit
  50.  
  51. DriveSpecOK:    Mov    AH,30h        ; Use DOS to get the 
  52.         Int    21h        ;   Version Number
  53.  
  54.         Cmp    AL,2        ; See if it's 2.0 or above 
  55.         Jae    DosVersOK    ; If so, proceed    
  56.  
  57.         Lea    DX,DosVersError    ; Otherwise print an error message!
  58.         Jmp    ErrorExit    ; Print message & exit 
  59.  
  60. ;    Get disk drive for tree
  61. ;    -----------------------
  62.  
  63. DosVersOK:    Mov    AL,[FCB]    ; Get drive parameter from FCB
  64.         Or    AL,AL        ; See if it's zero (default)
  65.         Jnz    NotDefault    ; If not, skip a few instructions
  66.  
  67.         Mov    AH,19h        ; Get default drive
  68.         Int    21h        ;   by calling DOS
  69.  
  70.         Inc    AL        ; Turns drive A: = 0 to drive A: = 1
  71.  
  72. NotDefault:    Mov    DL,AL        ; Set DL to drive number (A: = 1)
  73.         Add    AL,'@'        ; Convert to character "A", etc
  74.         Mov    [SearchAsciiz],AL    ; Put it in our search string
  75.         Cld            ; All string directions forward
  76.  
  77. ;    Do *.* search for sub-directories
  78. ;    ---------------------------------
  79.  
  80. MainLoop:    Mov    DX,[DTAPointer]        ; Get current DTA address
  81.         Mov    AH,1Ah            ; Set the DTA
  82.         Int    21h            ;   by calling DOS
  83.  
  84.         Mov    BX,[LevelsIn]        ; BX represents level
  85.         Add    BX,BX            ; Double it for addressing
  86.         Cmp    [FirstOrNext],0        ; See if this is first search
  87.         Jnz    FindNextFile        ; If not, skip some code 
  88.  
  89.         Mov    Word Ptr [SubDirCounter + BX],0    ; Count starts at 0
  90.  
  91.         Mov    DX,Offset SearchAsciiZ    ; Directory to search for
  92.         Mov    CX,10h            ; Directory attribute search
  93.         Mov    AH,4Eh            ; Find first file
  94.         Int    21h            ;   by calling DOS
  95.  
  96.         Jmp    Short TestMatch        ; See if we've got match
  97.  
  98. FindNextFile:    Mov    AH,4Fh            ; Otherwise find next file
  99.         Int    21h            ;   by calling DOS
  100.  
  101. TestMatch:    Jnc    TestAttr        ; If CY flag not set, continue
  102.         Jmp    NoMoreFiles        ; Otherwise, no more files
  103.  
  104. TestAttr:    Mov    SI,[DTAPointer]        ; SI now points to DTA
  105.         Cmp    Byte Ptr [SI + 21],10h    ; Test if a directory
  106.         Jnz    FindNextFile        ; If not, loop up for next
  107.  
  108. FoundDirEntry:    Add    SI,30            ; SI points to directory name
  109.         Cmp    Byte Ptr [SI],'.'    ; See if it's . or .. entry
  110.         Jz    FindNextFile        ; If so, loop up for next
  111.  
  112. ;    Have found a valid directory entry
  113. ;    ----------------------------------
  114.  
  115.         Inc    Word Ptr [SubDirCounter + BX]    ; Got another one
  116.         Mov    CX,[LevelsIn]        ; Number of levels deep
  117.         Jcxz    LookAheadSearch        ; If root, skip indentation
  118.  
  119.         Cmp    Word Ptr [SubDirCounter + BX],1    ; See if first found
  120.         Jz    NoSpaceIn        ; If so, no indentations
  121.  
  122.         Sub    BX,BX            ; Start index at zero
  123.  
  124. IndentLoop:    Mov    AL,179            ; Vertical line character
  125.         Test    Word Ptr [SubDirCounter + BX],8000h
  126.         Jz    GotContinueChar        ; Use if still more dirs left
  127.  
  128.         Mov    AL,' '             ; Otherwise use a blank
  129. GotContinueChar:Call    PrintChar        ; And print it
  130.  
  131.         Push    CX            ; Save the levels count
  132.  
  133.         Mov    CX,16            ; Need 16 blanks indentation
  134. BlankLoop:    Mov    AL,' '            ; This is the blank
  135.         Call    PrintChar        ; We print it
  136.         Loop    BlankLoop        ; And loop for the next
  137.  
  138.         Pop    CX            ; Retrieve the levels count
  139.  
  140.         Inc    BX            ; Kick up the levels index
  141.         Inc    BX            ; Twice because word access
  142.  
  143.         Loop    IndentLoop        ; Loop for all the levels
  144.  
  145. NoSpaceIn:    Cmp    Word Ptr [SubDirCounter + BX],1    ; See if first one
  146.         Jnz    LookAheadSearch        ; If not skip a little
  147.  
  148.         Mov    CX,[DashCount]        ; Number of lines to print
  149. DashPrint:    Mov    AL,196            ; Horizontal line character
  150.         Call    PrintChar        ; Print them
  151.         Loop    DashPrint        ; And loop for whole count
  152.  
  153. ;    Check for more directories to determine proper line characters
  154. ;    --------------------------------------------------------------
  155.  
  156. LookAheadSearch:Push    SI            ; Save ptr to directory name 
  157.  
  158.         Mov    SI,[DtaPointer]        ; Set source to DTA
  159.         Mov    DI,Offset DefaultDTA    ; Set destination to 80h
  160.         Mov    DX,DI            ; Also DX (used later)
  161.         Mov    CX,43            ; 43 characters to transfer
  162.         Rep    Movsb            ; Move them in
  163.  
  164.         Pop    SI            ; Get back directory name ptr
  165.  
  166.         Mov    AH,1Ah            ; Set a new DTA
  167.         Int    21h            ;   by calling DOS
  168.  
  169. CheckIfAnyMore:    Mov    AH,4Fh            ; Find the next file
  170.         Int    21h            ;   by calling DOS
  171.         Jc    CantFindAnother        ; CY set if can't find one
  172.  
  173.         Cmp    Byte Ptr [DefaultDTA + 21],10h    ; Test if a directory
  174.         Jnz    CheckIfAnyMore        ; If not, gotta try again
  175.         
  176.         Mov    AL,194            ; Horizontal w/ vertical below
  177.         Cmp    Word Ptr [SubDirCounter + BX],1
  178.         Jz    GotGoodChar        ; This is good if it's first
  179.  
  180.         Mov    AL,195            ; Vertical w/ horizontal right
  181.         Jmp    Short GotGoodChar    ; Other than first found
  182.  
  183. CantFindAnother:Mov    AL,196            ; Horizontal line character
  184.         Cmp    Word Ptr [SubDirCounter + BX],1
  185.         Jz    GotGoodChar        ; This is good if first one
  186.  
  187.         Mov    AL,192            ; Lower left corner
  188.         Or    Word Ptr [SubDirCounter + BX],8000h    ; Flag no more
  189.  
  190. GotGoodChar:    Call    PrintChar        ; Print that character also
  191.  
  192.         Mov    AL,196            ; Horizontal line character
  193.         Call    PrintChar        ; Another print
  194.  
  195.         Mov    AL,' '            ; Space before file name
  196.         Call    PrintChar        ; Print the space
  197.  
  198. ;    Now print name of directory and append to SearchPointer string
  199. ;    --------------------------------------------------------------
  200.  
  201.         Mov    CX,13        ; Number of characters in name
  202.         Mov    DI,[SearchPointer]    ; End of current search asciiz
  203.  
  204. PrintNameLoop:    Lodsb            ; Get the directory name character
  205.         Or    AL,AL        ; Check if it's zero terminator
  206.         Jz    EndOfName    ; If so, we're at the end
  207.  
  208.         Stosb            ; Save on end of search asciiz
  209.         Call    PrintChar    ; And print it also    
  210.  
  211.         Loop    PrintNameLoop    ; Loop for maximum number of chars
  212.  
  213. EndOfName:    Mov    AL,' '        ; Stick a blank at the end
  214.         Call    PrintChar    ; Print the blank
  215.         Mov    [DashCount],CX    ; Save for later dashes at end
  216.  
  217. FixUpSearch:    Mov    [SearchPointer],DI    ; New end of asciiz string
  218.         Inc    [SearchPointer]        ; Point to next character
  219.         Mov    SI,Offset SearchString    ; Will move in \*.*,0 string
  220.         Mov    CX,5            ; It's only five characters
  221.         Rep    Movsb            ; Move it ine
  222.  
  223.         Inc    [LevelsIn]        ; We're one level deeper now
  224.         Mov    [FirstOrNext],0        ; Prepare for search first
  225.         Add    [DtaPointer],43        ; New DTA will be needed
  226.         Jmp    MainLoop        ; Back up to beginning
  227.  
  228. ;    When no more files are found, time to back up to previous subdirectory
  229. ;    ---------------------------------------------------------------------- 
  230.  
  231. NoMoreFiles:    Cmp    [LevelsIn],0        ; See if we're back in root
  232.         Jz    Terminate        ; If so, we're all done!
  233.  
  234.         Test    Word Ptr [SubDirCounter + BX],7FFFh
  235.         Jnz    BackUpOneDir        ; If at least one file found
  236.  
  237.         Mov    AL,13            ; A carriage return
  238.         Call    PrintChar        ;   is printed
  239.         Mov    AL,10            ; A line feed
  240.         Call    PrintChar        ;   makes a new line 
  241.  
  242. BackUpOneDir:    Mov    DI,Offset SearchAsciiz    ; Let's look at search string
  243.         Mov    CX,70            ; It could have 70 characters
  244.         Mov    AL,0            ; We'll search for a zero
  245.         Repnz    Scasb            ; Let's do it
  246.  
  247.         Dec    DI            ; So points to zero
  248.  
  249.         Mov    CX,64            ; Now we'll search backwards
  250.         Mov    AL,'\'            ; For last slash
  251.         Std                ; Backwards search
  252.         Repnz    Scasb            ; Do it once
  253.         Repnz    Scasb            ; Again for dir we're leaving
  254.  
  255.         Inc    DI            ; So points to slash
  256.         Mov    [SearchPointer],DI    ; New end of asciiz string
  257.         Inc    [SearchPointer]        ; Actually one character more
  258.  
  259.         Mov    SI,Offset SearchString    ; Now append \*.*,0 to it
  260.         Mov    CX,5            ; Five characters
  261.         Cld                ; In forward direction
  262.         Rep    Movsb            ; Move them int
  263.  
  264.         Dec    [LevelsIn]        ; We go back one level
  265.         Mov    [FirstOrNext],1        ; Have to search next, not 1st
  266.         Sub    [DtaPointer],43        ; Previous DTA will be used
  267.         Jmp    MainLoop        ; Back up to beginning 
  268.  
  269. Terminate:    Int    20h            ; Terminate program
  270.  
  271. ;    PrintChar subroutine -- prints a character on the screen
  272. ;    --------------------------------------------------------
  273.  
  274. PrintChar:    Push    DX
  275.  
  276.         Mov    DL,AL        ; DL gets the character
  277.         Mov    AH,2        ; Print character on display
  278.         Int    21h        ;   by calling DOS
  279.  
  280.         Pop    DX
  281.  
  282.         Ret
  283.  
  284. ;    Other data areas here at end so COM file short as possible
  285. ;    ----------------------------------------------------------
  286.  
  287. SubDirCounter    Label    Word                ; Counts dir entries
  288.  
  289. EndProg        equ    64 + Offset SubDirCounter    ; DTAs go here
  290.  
  291. CSEG        EndS
  292.  
  293.         End Entry
  294.